using Abp.Runtime.Security;
using System;
using System.Linq;
using System.Security.Claims;
using System.Threading;

namespace Abp.Runtime.Session
{
    /// <summary>
    /// Implements <see cref="IAbpSession"/> to get session properties from claims of <see cref="Thread.CurrentPrincipal"/>.
    /// </summary>
    public class ClaimsAbpSession : IAbpSession
    {




        public Guid? AdminUserId
        {
            get
            {

                var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;
                if (claimsPrincipal == null)
                {
                    return null;
                }

                var claimsIdentity = claimsPrincipal.Identity as ClaimsIdentity;
                if (claimsIdentity == null)
                {
                    return null;
                }

                var userIdClaim = claimsIdentity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
                if (userIdClaim == null || string.IsNullOrEmpty(userIdClaim.Value))
                {
                    return null;
                }

                Guid userId;
                if (!Guid.TryParse(userIdClaim.Value, out userId))
                {
                    return null;
                }

                return userId;
            }

        }

        public string AdminUserName
        {
            get
            {

                var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;
                if (claimsPrincipal == null)
                {
                    return null;
                }

                var claimsIdentity = claimsPrincipal.Identity as ClaimsIdentity;
                if (claimsIdentity == null)
                {
                    return null;
                }

                var userNameClaim = claimsIdentity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name);
                if (userNameClaim == null || string.IsNullOrEmpty(userNameClaim.Value))
                {
                    return null;
                }

                return userNameClaim.Value;
            }
        }

        public Guid? CompanyId
        {
            get
            {

                var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;
                if (claimsPrincipal == null)
                {
                    return null;
                }

                var claimsIdentity = claimsPrincipal.Identity as ClaimsIdentity;
                if (claimsIdentity == null)
                {
                    return null;
                }

                var complanyIdClaim = claimsIdentity.Claims.FirstOrDefault(c => c.Type == AbpClaimTypes.ComplanyId);
                if (complanyIdClaim == null || string.IsNullOrEmpty(complanyIdClaim.Value))
                {
                    return null;
                }

                Guid complanyId;
                if (!Guid.TryParse(complanyIdClaim.Value, out complanyId))
                {
                    return null;
                }

                return complanyId;
            }
        }

        public string CompanyName
        {
            get
            {

                var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;
                if (claimsPrincipal == null)
                {
                    return null;
                }

                var claimsIdentity = claimsPrincipal.Identity as ClaimsIdentity;
                if (claimsIdentity == null)
                {
                    return null;
                }

                var complanyNameClaim = claimsIdentity.Claims.FirstOrDefault(c => c.Type == AbpClaimTypes.ComplanyName);
                if (complanyNameClaim == null || string.IsNullOrEmpty(complanyNameClaim.Value))
                {
                    return null;
                }

                return complanyNameClaim.Value;
            }
        }

        public Guid? RoleId
        {
            get
            {

                var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;
                if (claimsPrincipal == null)
                {
                    return null;
                }

                var claimsIdentity = claimsPrincipal.Identity as ClaimsIdentity;
                if (claimsIdentity == null)
                {
                    return null;
                }

                var roleIdClaim = claimsIdentity.Claims.FirstOrDefault(c => c.Type == AbpClaimTypes.RoleId);
                if (roleIdClaim == null || string.IsNullOrEmpty(roleIdClaim.Value))
                {
                    return null;
                }

                Guid roleId;
                if (!Guid.TryParse(roleIdClaim.Value, out roleId))
                {
                    return null;
                }

                return roleId;
            }
        }

        public string RoleName
        {
            get
            {

                var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;
                if (claimsPrincipal == null)
                {
                    return null;
                }

                var claimsIdentity = claimsPrincipal.Identity as ClaimsIdentity;
                if (claimsIdentity == null)
                {
                    return null;
                }

                var roleNameClaim = claimsIdentity.Claims.FirstOrDefault(c => c.Type == AbpClaimTypes.RoleName);
                if (roleNameClaim == null || string.IsNullOrEmpty(roleNameClaim.Value))
                {
                    return null;
                }

                return roleNameClaim.Value;
            }
        }

        public string SurName
        {
            get
            {

                var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;
                if (claimsPrincipal == null)
                {
                    return null;
                }

                var claimsIdentity = claimsPrincipal.Identity as ClaimsIdentity;
                if (claimsIdentity == null)
                {
                    return null;
                }

                var surNameClaim = claimsIdentity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Surname);
                if (surNameClaim == null || string.IsNullOrEmpty(surNameClaim.Value))
                {
                    return null;
                }

                return surNameClaim.Value;
            }
        }

        public int? CompanyType
        {
            get
            {

                var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;
                if (claimsPrincipal == null)
                {
                    return null;
                }

                var claimsIdentity = claimsPrincipal.Identity as ClaimsIdentity;
                if (claimsIdentity == null)
                {
                    return null;
                }

                var companyTypeClaim = claimsIdentity.Claims.FirstOrDefault(c => c.Type == AbpClaimTypes.CompanyType);
                if (companyTypeClaim == null || string.IsNullOrEmpty(companyTypeClaim.Value))
                {
                    return null;
                }

                return Conv.ToInt32OrNull(companyTypeClaim.Value);
            }
        }

        public string CompanyAreaId
        {
            get
            {

                var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;
                if (claimsPrincipal == null)
                {
                    return null;
                }

                var claimsIdentity = claimsPrincipal.Identity as ClaimsIdentity;
                if (claimsIdentity == null)
                {
                    return null;
                }

                var companyAreaIdClaim = claimsIdentity.Claims.FirstOrDefault(c => c.Type == AbpClaimTypes.ComplanyAreaId);
                if (companyAreaIdClaim == null || string.IsNullOrEmpty(companyAreaIdClaim.Value))
                {
                    return null;
                }

                return companyAreaIdClaim.Value;
            }
        }
    }
}